데이터 파이프라인 레거시를 보다보면, 절차적이다 못해 완전한 직렬 처리를 종종 본다.
파일이 100개다.
파일 1번 ftp 입수 -> 파일 정제 -> hdfs 이동 -> hive 정제 -> 목적 DB 저장
목적 DB 저장이 끝나면 어떻게 되나?
다시 2번 ftp 입수가 일어난다. (대충 그 짤)
시간이 많이 걸리고 노는 자원은 많다. 시간이 많이 걸리니까 대기하는 놈들이 한 끗만 엉켜도 연쇄 배치 실패가 일어나며 이하 생략.
이를 극복한다고 병렬 처리를 때린다. 이제 자원 경쟁이 심화되면서 불특정의 오류가 발생하기 시작한다.
간단하게는 에어플로우에서 올병렬 처리를 하고 풀링 제한을 두는 것이다. 그런데 이것도 완전히 똘똘한 것은 아니다.
멀티코어 CPU 인스트럭션 파이프와 같은 형태로 구성하는 것이 시간을 압도적으로 단축 시킬 수 있다.
입수 풀링 (100개 중 n개만 병렬, IO 부하에 맞춰 n개 결정) -> 입수가 끝난 놈들만 이어서 정제 풀링 (CPU 부하에 맞춰 m개 결정) -> hdfs 풀링 (IO 부하에 맞춰 k개 결정) ....
이러면 정제하는 동안도 입수를 하고 hdfs 를 복사하는 중에도 입수와 정제를 하며 .. 등등이다.
이렇게 까지 하기 귀찮다면 1개 파일 처리가 5개의 stage 가 있다고 했을때, 100개의 병렬 task에 각 task는 5개의 직렬 stage로 하고 풀링 제한만 두는 것도 괜찮다. 100개이므로 task는 동적 생성하면 된다. 동적 생성시에 무거운 작업이 뒤에 떨어지면 전체 소요 시간에서 손해가 있으므로 동적 태스크 생성 함수에 가중치를 받도록 하면 된다. 에어플로우는 배열 타입으로 병렬 태스크를 줄 수 있으므로 가중치가 있는 딕셔너리나 튜플의 배열로 처리하고 소팅한 후 키 값으로 배열을 다시 넘기는 것 만으로도 쉽게 처리 할 수 있다.
그런데 사실 bash 만으로도 풀링은 가능하다. (대충 자세한 설명은 생략한다 그 짤)